package cn.cmcc.online.smsapi.sdk.service.pubId;

import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import android.util.Log;
import cn.cmcc.online.smsapi.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.cmcc.online.smsapi.sdk.Iservice.XyCallBack;
import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.db.ParsePhonePubIdManager;
import cn.cmcc.online.smsapi.sdk.db.entity.IccidInfo;
import cn.cmcc.online.smsapi.sdk.db.entity.IccidInfoManager;
import cn.cmcc.online.smsapi.sdk.dex.DexUtil;
import cn.cmcc.online.smsapi.sdk.iccid.IccidLocationUtil;
import cn.cmcc.online.smsapi.sdk.log.LogManager;
import cn.cmcc.online.smsapi.sdk.net.NetUtil;
import cn.cmcc.online.smsapi.sdk.net.NewXyHttpRunnable;
import cn.cmcc.online.smsapi.sdk.net.util.ServerUtil;
import cn.cmcc.online.smsapi.sdk.queue.SdkTaskQueue;
import cn.cmcc.online.smsapi.sdk.queue.TaskInfo;
import cn.cmcc.online.smsapi.sdk.util.DuoquUtils;
import cn.cmcc.online.smsapi.sdk.util.JsonUtil;
import cn.cmcc.online.smsapi.sdk.util.StringUtils;
import cn.cmcc.online.smsapi.sdk.util.ThreadPoolManager;
import cn.cmcc.online.smsapi.sdk.util.XyUtil;
import cn.cmcc.online.smsapi.util.SdkCallBack;

public class ParsePhonePubIdService {

    public static final int RESULT_TOKEN_FLASH = 403;// token过期
    public static final int RESULT_SERVER_ERROR = 404;// 服务器错误
    public static final int RESULT_NO_NET = 405;// 没有网络
    public static final int RESULT_SUCESS = 200;// 成功返回
    public static String PHONE_PUBID_UPDATE_STEP = "10";

    /*
     * 批量更新接口
     */
    public static void batchUpdatePubId() {

        try {
            JSONArray qureyJsonArray = null;
            long queryTime = checkQueryUpdateCycle(
                    OnlineUpdateCycleConfigInterface.TYPE_QUERY_BATCH_PHONE_NULL_PUB_ID_UPDATE_CYCLE,
                    Constant.week);
            qureyJsonArray = ParsePhonePubIdManager.queryPubIdByDateAndUpdate(queryTime, PHONE_PUBID_UPDATE_STEP, true);
            int cnt = 0;
            while (!StringUtils.isNull(qureyJsonArray.toString()) && qureyJsonArray.length() != 0) {
                queryPubIdByNet(qureyJsonArray);
                qureyJsonArray = ParsePhonePubIdManager.queryPubIdByDateAndUpdate(queryTime, PHONE_PUBID_UPDATE_STEP,
                        true);
                cnt++;
                if (cnt > 1000) {
                    break;
                }
                Thread.sleep(1);
            }
            // 更新失败的情况下，标记位还原
            /* SDK-499 hewegnao 20160621 start */
            ParsePhonePubIdManager.updateQueryFlag(true);
            /* SDK-499 hewegnao 20160621 end */

            long queryTime1 = checkQueryUpdateCycle(
                    OnlineUpdateCycleConfigInterface.TYPE_QUERY_BATCH_PHONE_PUB_ID_UPDATE_CYCLE,
                    Constant.week);
            qureyJsonArray = ParsePhonePubIdManager.queryPubIdByDateAndUpdate(queryTime1, PHONE_PUBID_UPDATE_STEP,
                    false);
            cnt = 0;
            while (!StringUtils.isNull(qureyJsonArray.toString()) && qureyJsonArray.length() != 0) {
                queryPubIdByNet(qureyJsonArray);
                qureyJsonArray = ParsePhonePubIdManager.queryPubIdByDateAndUpdate(queryTime1, PHONE_PUBID_UPDATE_STEP,
                        false);
                cnt++;
                if (cnt > 1000) {
                    break;
                }
                Thread.sleep(1);
            }
            // 更新失败的情况下，标记位还原
            /* SDK-499 hewegnao 20160621 start */
            ParsePhonePubIdManager.updateQueryFlag(true);
            /* SDK-499 hewegnao 20160621 end */
        }
        catch (Throwable e) {
            // TODO: handle exception
            LogManager.e(Constant.TAG, "batchUpdatePubId: ", e);
        }
        // }

    }

    // public static void recoverDateBase(){
    // ParsePhonePubIdManager.queryAndUpdateQueryFlag();
    // }

    public static long time;

    public static void preloadPubId(final String phone) {
        ThreadPoolManager.UPDATE_SERVICE.execute(new Runnable() {

            @Override
            public void run() {
                time = System.currentTimeMillis();
                if (phone != null) {
                    LogManager.e("ParsePhone", "cacheOrDb preload phone= " + phone + " time :" + time);
                    String pubId = ParsePhonePubIdManager.getPubIdByCache(phone);
                    if (StringUtils.isNull(pubId)) {
                        pubId = ParsePhonePubIdManager.querySinglePubId(phone);
                        LogManager.e("ParsePhone", "cacheOrDb preload phone= " + phone + " pubId=" + pubId
                                + " disTime:" + (System.currentTimeMillis() - time));
                        if (!StringUtils.isNull(pubId))
                            ParsePhonePubIdManager.setPubIdByCache(phone, pubId);
                        else {
                            queryPubIdByNet(phone);
                        }
                    }

                }
            }
        });

    }

    private static void queryPubIdByNet(final String phone) {
        final long time2 = System.currentTimeMillis();
        LogManager.e("ParsePhone", "queryPubIdByNet start" + phone + " time :" + time2);
        if (!NetUtil.hasNewToken(null)) {
            LogManager.e("xiaoyuan", "queryPubIdByNet not hasNewToken");
            return;
        }
        try {
            SdkCallBack sdkCallBack = new SdkCallBack() {

                @Override
                public void execute(Object... obj) {
                    try {
                        if (obj != null && obj.length >= 2) {
                            if ((Integer) obj[0] == 0) {
                                String response = (String) obj[1];
                                JSONArray jsonArray = new JSONArray(response);
                                Log.e("ParsePhonePubidService", response + "");
                                for (int i = 0; i < jsonArray.length(); i++) {
                                    JSONObject jb = jsonArray.optJSONObject(i);
                                    ParsePhonePubIdManager.setPubIdByCache(phone, jb.optString("pubId"));
                                }
                                LogManager.e("ParsePhone",
                                        "queryPubIdByNet end" + phone + " distime :"
                                                + (System.currentTimeMillis() - time2));
                                ParsePhonePubIdManager.saveOrUpdate(jsonArray);
                            }
                        }
                    }
                    catch (Throwable t) {
                        LogManager.e(Constant.TAG, "queryPubIdByNet", t);
                    }
                }
            };
            String dataString = "{\"arr\":[\"" + phone + "\"]}";
            NetUtil.executeNewServiceHttpRequest(NetUtil.URL_PUB_NUMBER, dataString, sdkCallBack, true, false, true,
                    null);
        }
        catch (Throwable t) {
            LogManager.e(Constant.TAG, "queryPubIdByNet: ", t);
        }
    }

    /*
     * 网上批量更新
     */

    public static void queryPubIdByNet(JSONArray newjsonArray) {
        if (newjsonArray.length() == 0) {
            return;
        }
        try {
            StringBuffer areaCodeCard = new StringBuffer();
            getAreaCode(areaCodeCard);
            if (!NetUtil.hasNewToken(null)) {
                LogManager.e("xiaoyuan", "queryPubIdByNet not hasNewToken");
                return;
            }

            final String dataString = ServerUtil.getQueryPubIdReq(areaCodeCard.toString(), newjsonArray);
            if (!StringUtils.isNull(dataString)) {
                /* SDK-526 huangzhiqiang 20160713 start */
                NetUtil.requestNewTokenIfNeed(null);
                final String token = NetUtil.getToken();
                /* SDK-526 huangzhiqiang 20160713 end */
                XyCallBack reqcallBack = new XyCallBack() {

                    @Override
                    public void execute(Object... obj) {
                        if (obj != null && obj.length > 0) {
                            String resultCode = obj[0].toString();
                            if (resultCode.equals(NewXyHttpRunnable.ERROR_CODE_TOKEN_FAILED)) {
                                /* SDK-526 huangzhiqiang 20160713 start */
                                NetUtil.requestNewTokenAndPostRequestAgain(NetUtil.URL_PUB_NUMBER, dataString,
                                        Constant.FIVE_MINUTES, false, false, true, null, token, this);
                                return;
                                /* SDK-526 huangzhiqiang 20160713 end */
                                // recoverDateBase();
                                // XyUtil.doXycallBackResult(null, null,
                                // RESULT_TOKEN_FLASH);
                            }

                            if (resultCode.equals(NewXyHttpRunnable.ERROR_CODE_PARE_ERR)
                                    || resultCode.equals(NewXyHttpRunnable.ERROR_CODE_SERVICE_ERR)) {
                                // 网络失败
                                // recoverDateBase();
                                // XyUtil.doXycallBackResult(null, null,
                                // RESULT_NO_NET);
                            }
                            else {
                                if (resultCode.equals("0") && obj.length == 2) {
                                    String response = obj[1].toString();
                                    if (StringUtils.isNull(response)) {
                                        // recoverDateBase();
                                        XyUtil.doXycallBackResult(null, null, RESULT_SERVER_ERROR);
                                    }
                                    else {
                                        try {
                                            JSONArray jsonArray = new JSONArray(response);
                                            // 入库并放入缓存
                                            ParsePhonePubIdManager.saveOrUpdate(jsonArray);
                                            // ParsePhonePubIdManager.insertCatch(jsonArray);
                                            // 更新查询时间
                                            ParsePhonePubIdManager.updateQueryFlag(true);
                                        }
                                        catch (Exception e) {
                                            // e.printStackTrace();
                                            // recoverDateBase();
                                            LogManager.e(Constant.TAG, "checkValidUrlNetBatch: ", e);
                                            XyUtil.doXycallBackResult(null, null, RESULT_SERVER_ERROR);

                                        }
                                    }
                                }
                                else {
                                    // recoverDateBase();
                                    // XyUtil.doXycallBackResult(null, null,
                                    // RESULT_SERVER_ERROR);
                                }
                            }
                        }
                        else {
                            // recoverDateBase();
                            // XyUtil.doXycallBackResult(null, null,
                            // RESULT_SERVER_ERROR);
                        }
                    }

                };
                NetUtil.executeNewServiceHttpRequest(NetUtil.URL_PUB_NUMBER, dataString, reqcallBack, false, false,
                        true, null);
            }
        }
        catch (Exception e) {
            LogManager.e(Constant.TAG, "checkValidUrlNet: ", e);

        }
    }

    /**
     * 网络查询
     */
    public static void queryPubIdService(String phoneNum, String dbresoult) {
        // LogManager.e("xiaoyuan",
        // "phoneNum: "+phoneNum+" dbresoult: "+dbresoult);
        if ("true".equalsIgnoreCase(dbresoult)) {
            try {
                HashMap<String, String> map = new HashMap<String, String>();

                map.put("pubId", "");
                map.put("phone", phoneNum);
                map.put("querytime", "0");
                map.put("queryflag", "0");
                ParsePhonePubIdManager.saveOrUpdateSingleDate(map);
            }
            catch (Exception e) {
                // TODO: handle exception
                LogManager.e(Constant.TAG, "queryPubIdFromNet: ", e);
            }
        }
        /* SDK-499 hewengao 20160621 start */
        if (NetUtil.isEnhance() && NetUtil.checkAccessNetWork(1)) {// wifi环境下，才可以批量更新
            /* SDK-499 hewengao 20160621 end */
            IccidLocationUtil.queryAreaCode(true);// 网络获取省份域码，同步操作
            batchUpdatePubId();
        }

    }

    /**
     * 查询依据号码获取脚本公众号ID入口
     * 
     * */
    public static String queryPubIdByPhoneNum(String phoneNum) {
        String value = null;
        String cacheValue = null;// 缓存值
        JSONObject resoult = null;
        String result = "false";// 返回结果
        LogManager.d("xiaoyaun", "#########queryPubIdByPhoneNum : ", phoneNum);
        if (phoneNum != null) {
            try {
                cacheValue = ParsePhonePubIdManager.getPubIdByCache(phoneNum);// 先查询缓存
                if (!StringUtils.isNull(cacheValue)) {
                    result = "false";
                    return cacheValue;
                }
                resoult = ParsePhonePubIdManager.queryPubId(phoneNum);// 查数据库
                if (resoult != null) {// 数据库无记录
                    ParsePhonePubIdManager.setPubIdByCache(resoult.getString("phone"), resoult.getString("pubId"));
                    value = resoult.getString("pubId");
                    result = "false";
                    if (!StringUtils.isNull(value)) {// 数据库中pubid为空
                        return value;
                    }
                }
                LogManager.i("parsePhone", phoneNum + " time = " + System.currentTimeMillis());
                result = "true";

            }
            catch (Throwable e) {
                LogManager.e(Constant.TAG, "queryPubIdByPhoneNum: ", e);
            }
            finally {
                // LogManager.e("xiaoyaun",
                // "#########queryPubIdByPhoneNum phoneNum: "+phoneNum+"   dbresoult: "+result
                // );
                // LogManager.i("parsePhone", phoneNum + " pubId = " + value);
                SdkTaskQueue.addTask(new TaskInfo(13, "phoneNum", phoneNum, "dbresoult", result));
            }
        }
        return null;
    }

    private static long checkQueryUpdateCycle(int cycleType, long defaultCycle) {

        long time = DexUtil.getUpdateCycleByType(cycleType, defaultCycle);
        return (System.currentTimeMillis() - time);
    }

    /**
     * 从卡中获取区域码
     */
    private static String getCardAreaCode(int simIndex) {
        JSONObject res = null;
        res = DuoquUtils.getSdkDoAction().getProviceAndSP(simIndex);
        try {
            if (res == null) {
                IccidInfo icc = IccidInfoManager.queryDeftIccidInfo(Constant.getContext());
                if (icc != null) {
                    return icc.areaCode;
                }
            }
            else {
                String p = (String) JsonUtil.getValueFromJsonObject(res, "provice");
                String pcode = IccidInfoManager.getProviceCode(p);
                if (pcode != null) {
                    return pcode;
                }
            }
        }
        catch (Throwable e) {
            LogManager.e(Constant.TAG, "getCardAreaCode: ", e);
        }
        return null;
    }

    /**
     * 拼接获取区域码
     */
    private static void getAreaCode(StringBuffer areaCodeCard) {
        StringBuffer areaCodeCard1 = new StringBuffer();
        StringBuffer areaCodeCard2 = new StringBuffer();
        areaCodeCard1 = areaCodeCard1.append(getCardAreaCode(0));
        areaCodeCard2 = areaCodeCard2.append(getCardAreaCode(1));
        if (StringUtils.isNull(areaCodeCard1.toString()) && StringUtils.isNull(areaCodeCard2.toString())) {
            areaCodeCard.append("CN");
        }
        else if (StringUtils.isNull(areaCodeCard1.toString()) && !StringUtils.isNull(areaCodeCard2.toString())) {
            areaCodeCard.append(areaCodeCard2.toString());
        }
        else if (StringUtils.isNull(areaCodeCard2.toString()) && !StringUtils.isNull(areaCodeCard1.toString())) {
            areaCodeCard.append(areaCodeCard1.toString());
        }
        else {
            areaCodeCard.append(areaCodeCard1.toString()).append(",").append(areaCodeCard2.toString());
        }
    }

    public static void loadPubId(List<String> phoneNumbers) {
        List<String> localNumbers = ParsePhonePubIdManager.queryAllNumber(false);
        if (phoneNumbers == null)
            return;
        if(localNumbers!=null){
            int size = phoneNumbers.size();
            for (int i = size - 1; i >= 0; i--) {
                String phone = phoneNumbers.get(i);
                if (localNumbers.contains(phone)) {
                    phoneNumbers.remove(phone);
                }
            }
        }
        LogManager.i("ParsePhone", "loadPubId array " + phoneNumbers.toString());
        if (phoneNumbers.size() > 0) {

            try {
                JSONArray jsonArray = new JSONArray();
                for (String phone : phoneNumbers) {
                    jsonArray.put(phone);
                }
                queryPubIdByNet(jsonArray);
            }
            catch (Throwable t) {
                LogManager.i("ParsePhone", t.toString());
            }
        }

    }

}
